<template>
  <a-result v-if="noAccess" status="403" title="您不是该流程的参与者或管理员，请不要越权访问！" />
  <div v-else class="defaut-flow-detail" :class="'flow-detail-page ' + (eformMode + ' ' + viewMode + ' ' + flowDetailBody)">
    <a-layout v-show="lockLoading" class="flow-detail-card">
      <a-layout-content class="flow-content">
        <a-spin :spinning="loadingSaveState || loading" wrapper-class-name="flow-detail-content-spin" :tip="loadingTips" size="large">
          <div class="flow-content-wrapper" :class="{ 'flow-content-wrapper-push-down': flowDetailShowType === 'pushDown' }">
            <div v-show="viewMode !== 'detailForm'" class="flow-content-top">
              <avic-bpm-head
                :params="params"
                :flow-custom-vars="flowCustomVars"
                :is-scroll-down="isScrollDown"
                :bpm-instance-object="bpmInstanceObject"
                :show-bpm-tabs="flowDetailShowType == 'pushDown' ? false : true"
                :before-bpm-buttons="beforeBpmButtons"
                @saveAndStartProcess="saveAndStartProcess"
                @saveForm="saveForm"
                @afterBpmButtons="afterBpmButtons"
                @flowCustomFunction="flowCustomFunction"
                @scrollViewByTab="scrollViewByTab"
                @selectSubFlow="selectSubFlow"
                @selectParentFlow="selectParentFlow"
                @BpmButTrack="BpmButTrack"
              />
            </div>

            <div ref="flowBody" class="flow-content-body">
              <div
                class="bpm-pic-tab"
                :class="
                  Object.assign(
                    { formDetail: viewMode == 'detailForm' },

                    eformMode == 'inModal' ? avicTopPanelClass : {}
                  )
                "
              >
                <a-collapse
                  v-if="flowDetailShowType === 'collapse'"
                  v-model:activeKey="activeKey"
                  :bordered="false"
                  class="flow-detail-collapse"
                >
                  <template v-for="(item, index) in bpmTabs">
                    <a-collapse-panel v-if="item.display == '1'" :key="index">
                      <template #header>
                        <div :ref="item.id" style="padding: 12px 0">{{ item.name }}</div>
                      </template>
                      <div :key="item.id" class="section-content">
                        <div v-if="item.display == '1'" class="section-title">
                          <a v-if="item.id == 'bpm_pic_tab' && item.display == '1'" @click="changeTabs">
                            {{ switchTitle }}
                          </a>
                          <span v-if="item.id == 'bpm_track_tab' && item.display == '1'" class="flow-tabs">
                            <a-radio-group v-model:value="currentTab" button-style="solid">
                              <a-radio-button v-for="(tab, i) in tabs" :key="i" :value="tab.type" @change="changeHeadTag(tab)">
                                <avic-icon :svg="tab.svg" />
                              </a-radio-button>
                            </a-radio-group>
                          </span>
                        </div>
                        <div class="section-iframe">
                          <component
                            :is="detailVueCompnent"
                            v-if="item.id == 'bpm_form_tab'"
                            ref="flowDetail"
                            :params="params"
                            :micro-params="microParams"
                            :bpm-instance-object="bpmInstanceObject"
                            @changeFlowCustomVars="changeFlowCustomVars"
                          />
                          <div v-if="item.id == 'bpm_idea_tab' && item.display == '1'" class="main">
                            <avic-bpm-opinion :bpm-instance-object="bpmInstanceObject" />
                          </div>
                          <div v-if="item.id == 'bpm_pic_tab' && item.display == '1'" class="main">
                            <avic-bpm-track-and-chart :is-steps="isSteps" :bpm-instance-object="bpmInstanceObject" />
                          </div>
                          <div v-if="item.id == 'bpm_track_tab' && item.display == '1'" class="main">
                            <avic-bpm-tracking :bpm-instance-object="bpmInstanceObject" :current-tab="currentTab" />
                          </div>
                          <div
                            v-if="
                              !['bpm_form_tab', 'bpm_idea_tab', 'bpm_pic_tab', 'bpm_track_tab'].includes(item.id) && item.display == '1'
                            "
                            class="main"
                          >
                            <bpm-tabs-extend :key="item.id" :bpm-instance-object="bpmInstanceObject" :tab-id="item.id" />
                          </div>
                        </div>
                      </div>
                    </a-collapse-panel>
                  </template>
                  <template #expandIcon="{ isActive }">
                    <double-right-outlined :rotate="isActive ? 90 : 270" />
                  </template>
                </a-collapse>
                <a-tabs v-if="flowDetailShowType === 'tab'" v-model:activeKey="activeKey1" class="bpm-flow-tab">
                  <template v-for="(item, index) in bpmTabs">
                    <a-tab-pane v-if="item.display == '1'" :key="String(index)" :force-render="true">
                      <div :key="item.id" class="section-content">
                        <div v-if="item.display == '1'" class="section-title1">
                          <a v-if="item.id == 'bpm_pic_tab' && item.display == '1'" @click="changeTabs">
                            {{ switchTitle }}
                          </a>
                          <span v-if="item.id == 'bpm_track_tab' && item.display == '1'" class="flow-tabs">
                            <a-radio-group v-model:value="currentTab" button-style="solid">
                              <a-radio-button v-for="(tab, i) in tabs" :key="i" :value="tab.type" @change="changeHeadTag(tab)">
                                <avic-icon :svg="tab.svg" />
                              </a-radio-button>
                            </a-radio-group>
                          </span>
                        </div>
                        <div class="section-iframe">
                          <component
                            :is="detailVueCompnent"
                            v-if="item.id == 'bpm_form_tab'"
                            ref="flowDetail"
                            class="bpm_form_tab_box"
                            :params="params"
                            :micro-params="microParams"
                            :bpm-instance-object="bpmInstanceObject"
                            @changeFlowCustomVars="changeFlowCustomVars"
                          />
                          <div v-if="item.id == 'bpm_idea_tab' && item.display == '1'" class="main">
                            <avic-bpm-opinion :bpm-instance-object="bpmInstanceObject" />
                          </div>
                          <div v-if="item.id == 'bpm_pic_tab' && item.display == '1'" class="main">
                            <avic-bpm-track-and-chart :is-steps="isSteps" :bpm-instance-object="bpmInstanceObject" />
                          </div>
                          <div v-if="item.id == 'bpm_track_tab' && item.display == '1'" class="main">
                            <avic-bpm-tracking :bpm-instance-object="bpmInstanceObject" :current-tab="currentTab" />
                          </div>
                          <div
                            v-if="
                              !['bpm_form_tab', 'bpm_idea_tab', 'bpm_pic_tab', 'bpm_track_tab'].includes(item.id) && item.display == '1'
                            "
                            class="main"
                          >
                            <bpm-tabs-extend :key="item.id" :bpm-instance-object="bpmInstanceObject" :tab-id="item.id" />
                          </div>
                        </div>
                      </div>
                    </a-tab-pane>
                  </template>
                  <template #expandIcon="{ isActive }">
                    <double-right-outlined :rotate="isActive ? 90 : 270" />
                  </template>
                </a-tabs>
                <div v-if="flowDetailShowType === 'pushDown'" ref="addd" class="bpm-push-container">
                  <a-tabs v-if="showBpmButTrack" style="height: 50%">
                    <template #rightExtra>
                      <CloseOutlined @click="BpmButTrack" />
                    </template>
                    <template v-for="(item, index) in bpmTabs">
                      <a-tab-pane v-if="item.display == '1' && item.id !== 'bpm_form_tab'" :key="String(index)" :force-render="true">
                        <template #tab>
                          <div :ref="item.id" style="padding: 12px 0; font-size: 16px; font-weight: 600">{{ item.name }}</div>
                        </template>
                        <div :key="item.id" class="section-content">
                          <div class="section-iframe">
                            <div v-if="item.id == 'bpm_idea_tab' && item.display == '1'" class="main">
                              <avic-bpm-opinion :bpm-instance-object="bpmInstanceObject" />
                            </div>
                            <div v-if="item.id == 'bpm_pic_tab' && item.display == '1'" class="main">
                              <a-row justify="end" style="">
                                <a-col>
                                  <a v-if="fatherEntryId" href="javascript:void(0);" @click="unfoldFather">
                                    <avic-icon svg="avic-zoom-in-line" />
                                    查看父流程
                                  </a>
                                  <a @click="changeTabs">
                                    {{ switchTitle }}
                                  </a>
                                </a-col>
                              </a-row>
                              <avic-bpm-track-and-chart :is-steps="isSteps" :bpm-instance-object="bpmInstanceObject" />
                            </div>
                            <div v-if="item.id == 'bpm_track_tab' && item.display == '1'" class="main">
                              <a-row justify="end" style="height: 30px; line-height: 30px">
                                <a-col>
                                  <a-radio-group v-model:value="currentTab" button-style="solid">
                                    <a-radio-button v-for="(tab, i) in tabs" :key="i" :value="tab.type" @change="changeHeadTag(tab)">
                                      <avic-icon :svg="tab.svg" />
                                    </a-radio-button>
                                  </a-radio-group>
                                </a-col>
                              </a-row>
                              <avic-bpm-tracking :bpm-instance-object="bpmInstanceObject" :current-tab="currentTab" />
                            </div>
                          </div>
                        </div>
                      </a-tab-pane>
                    </template>
                  </a-tabs>
                  <div v-for="(item, index) in bpmTabs" :key="index">
                    <component
                      :is="detailVueCompnent"
                      v-if="item.display == '1' && item.id == 'bpm_form_tab'"
                      ref="flowDetail"
                      class="bpm_form_box"
                      :params="params"
                      :micro-params="microParams"
                      :bpm-instance-object="bpmInstanceObject"
                      @changeFlowCustomVars="changeFlowCustomVars"
                    />
                  </div>
                  <father-track
                    :show-bpm-open-form-but="true"
                    :entry-id="fatherEntryId"
                    :visible="fatherVisible"
                    :bpm-instance-object="bpmInstanceObject"
                    @closeFather="closeFather"
                  />
                </div>
              </div>
            </div>
          </div>
        </a-spin>
        <teleport-container />
      </a-layout-content>
    </a-layout>
  </div>
</template>

<script>
import { settings } from '@/settings';
import { AvicBpmHead } from '../bpm-head';
import AvicBpmContent from '../bpm-content';
import { AvicBpmOpinion } from '../bpm-opinion';
import bpmUtils from '@/views/avic/bpm/bpmutils/FlowUtils';
import BpmInstanceObject from '@/views/avic/bpm/bpmutils/FlowEditor';
import { isUserSecretLevel, httpAction } from '@/api/avic/bpm/FlowUtilApi';
import { useMultiTab } from '@/components/multi-tab/multi-tab-store';
import FatherTrack from '../bpm-buttons-modal/FatherTrack.vue';
import BpmTabsExtend from '@/extends/bpmtabs/index.vue';

// 流程图节点渲染
import { getTeleport } from '@antv/x6-vue-shape';

const TeleportContainer = getTeleport();
export default {
  name: 'FlowDetailContent',
  components: {
    TeleportContainer,
    AvicBpmOpinion,
    // eslint-disable-next-line import/no-named-as-default-member
    AvicBpmTrackAndChart: AvicBpmContent.AvicBpmTrackAndChart,
    AvicBpmHead,
    // eslint-disable-next-line import/no-named-as-default-member
    AvicBpmChart: AvicBpmContent.AvicBpmChart,
    // eslint-disable-next-line import/no-named-as-default-member
    AvicBpmTracking: AvicBpmContent.AvicBpmTracking,
    FatherTrack,
    BpmTabsExtend
  },
  provide() {
    return {
      checkUserAndFormSecretLevel: this.checkSecretLevel
    };
  },
  props: {
    // 非电子表单detailvue文件的component对象
    detailVueCompnent: {
      type: [Function, Object],
      required: true,
      default: null
    },
    // 非路由获取传参时使用
    params: {
      type: Object,
      required: false,
      default: null
    },
    viewMode: {
      type: String,
      required: false,
      default: ''
    },
    loadComponent: {
      type: Function,
      default: null
    }
  },
  data() {
    return {
      id: null,
      contentLastScrollTop: 0,
      isScrollDown: false,
      showBpmButTrack: false,
      openType: 'add',
      loadingTips: '正在加载流程表单',
      loadingSaveState: false,
      loading: false,
      bpmTabs: [], // 显示区域数据
      currentTab: 'tracking', // 文字跟踪当前展示tab页
      tabs: [
        { id: 1, name: '列表', type: 'list', svg: 'avic-list-unordered' },
        { id: 2, name: '时间轴', type: 'tracking', svg: 'avic-time-line' }
      ],
      getParentprocessParam: {
        url: `${bpmUtils.baseurl}/business/getParentprocess/v1`,
        method: 'post'
      },
      flowCustomVars: {},
      isSteps: false, // 流程意见显隐控制
      switchTitle: '查看时间轴',
      urlParams: {},
      modeStyle: {},
      eformMode: '',
      visible: false,
      preConfirmedModel: '',
      selectSubFlowCallback: '',
      microParams: {}, // 微前端配置项
      bpmInstanceObject: new BpmInstanceObject(),
      activeKey1: '0',
      activeKey: ['0', '1', '2', '3'],
      lockLoading: false,
      lockFlag: false,
      flowDetailBody: '',
      flowDetailShowType: '',
      fatherEntryId: '', // 父流程EntryId
      fatherVisible: false // 打开父流程
    };
  },
  computed: {
    noAccess() {
      return window.$config.flow?.defaultExtType !== '2' && this.bpmInstanceObject.bpmModel.userIdentityKey === '8';
    }
  },
  watch: {
    'bpmInstanceObject.bpmEditor.loadingState': {
      handler(val) {
        if (val) {
          this.loadingTips = '正在加载流程表单';
        }

        this.loading = val;
      }
    },
    'bpmInstanceObject.bpmEditor.loadingSaveState': {
      handler(val) {
        if (val) {
          this.loadingTips = '正在提交表单';
        }
        this.loadingSaveState = val;
      }
    },
    // 监听tab数据变化
    'bpmInstanceObject.bpmTabs.showTabs': {
      handler(tabs) {
        if (this.viewMode === 'detailForm') {
          this.bpmTabs = tabs.filter((value) => value.code === 'bpm_form_tab');
        } else {
          this.bpmTabs = tabs;
          this.activeKey = tabs.map((value, index) => index);
        }
      }
    }
  },
  beforeCreate() {
    // document.getElementsByTagName('body')[0].className = 'flow-detail-body';
  },
  created() {
    this.flowDetailShowType = settings.flowDetailShowType || 'collapse';
    const [{ close }] = useMultiTab();
    bpmUtils.close = close;
    if (this.params) {
      this.eformMode = 'inModal';
      const modeStyleHeight = this.viewMode === 'detailForm' ? '456px' : '400px';
      this.modeStyle = {
        height: modeStyleHeight
      };
      this.urlParams = this.params;
    } else {
      // 添加条件判断，避免dialog模式查看表单时js错误
      if (this.$route) {
        this.urlParams = this.$route.query;
      }
      if (this.$route?.params?.type === 'tab') {
        this.eformMode = 'inTab';
      }
    }
    if (this.eformMode === 'inModal' || this.eformMode === 'inTab') {
      this.flowDetailBody = 'flow-detail-body';
    } else {
      document.getElementsByTagName('body')[0].className = 'flow-detail-body';
      if (this.flowDetailShowType === 'pushDown') {
        document.getElementsByTagName('body')[0].className = 'flow-detail-body flow-detail-body-push';
      }
    }

    this.id = this.urlParams.id;
    this.openType = this.urlParams.id ? 'edit' : 'add';

    if (this.urlParams.siteType === '1') {
      this.microParams.id = this.urlParams.defineId;
      this.microParams.microAppName = this.urlParams.microAppName;
      this.microParams.microAppUrl = this.urlParams.microAppUrl;
      this.microParams.microAppSubUrl = `/${this.microParams.microAppName}`;
      this.microParams.microAppSubComponent = decodeURIComponent(this.$route.params.id).replace(RegExp('_', 'g'), '/');
    }

    this.setFlowData();
    this.getParentprocess();
    // // loadComponent方法测试代码
    // this.testCompnent = this.loadComponent('views/account/center/index');
  },
  mounted() {
    this.bpmTabs = this.bpmInstanceObject.bpmTabs.tabs;
    this.contentLastScrollTop = this.$refs.flowBody?.scrollTop || 0;
    this.$refs.flowBody?.addEventListener('scroll', this.handleScroll);

    // 刷新页面提示并关闭窗口
    if (this.openType === 'add') {
      this.refreshWindow();
    }
    // 定时器，主要处理当页面不校验用户表单密级时，显示流程页面使用
    const interval = setInterval(() => {
      if (this.$refs.flowDetail) {
        if (!this.lockFlag) {
          this.lockLoading = true;
        }
        clearInterval(interval);
      }
    }, 100);
  },
  methods: {
    /** 校验用户是否可查看高密级表单内容方法 */
    checkSecretLevel(secretLevelCodeValue) {
      // 当校验用户表单密级时，首先锁定mounted定时器中的显示内容，统一由以下方法处理显示
      this.lockFlag = true;
      this.lockLoading = false;
      const processInstanceId = this.bpmInstanceObject.bpmModel.entryId;
      if (processInstanceId) {
        const param = {
          processInstanceId: this.bpmInstanceObject.bpmModel.entryId,
          secretLevelCode: secretLevelCodeValue
        };
        isUserSecretLevel(param)
          .then((res) => {
            if (res.success) {
              if (!res.data) {
                this.openMessageAndCloseWindow();
              } else {
                this.lockLoading = true;
              }
            }
          })
          .catch(() => {
            this.lockLoading = true;
          });
      } else {
        this.lockLoading = true;
      }
    },
    openMessageAndCloseWindow() {
      let secondsToGo = 3;
      const modal = this.$Modal.warning({
        title: '密级校验失败',
        content: `对不起，当前用户密级低于表单密级，无法继续操作，表单将于 ${secondsToGo} 秒后自动关闭.`,
        maskStyle: { 'background-color': '#fff' },
        onOk() {
          window.close();
        }
      });
      const interval = setInterval(() => {
        secondsToGo -= 1;
        modal.update({
          content: `对不起，当前用户密级低于表单密级，无法继续操作，表单将于 ${secondsToGo} 秒后自动关闭.`
        });
      }, 1000);
      setTimeout(() => {
        clearInterval(interval);
        window.close();
        modal.destroy();
      }, secondsToGo * 1000);
    },
    setFlowData() {
      // 设置流程标题
      if (!this.params && this.eformMode !== 'inModal' && this.eformMode !== 'inTab') {
        bpmUtils.setTitle(this.urlParams.title);
      }

      if (this.openType === 'add') {
        if (!this.urlParams.defineId) {
          this.$message.error('系统错误缺少参数');
        }

        // 初始化流程按钮和参数
        this.bpmInstanceObject.bpmEditor.flowEditorInitFunc(this.bpmInstanceObject, {
          deploymentId: this.urlParams.deploymentId,
          defineId: this.urlParams.defineId
        });
      } else if (this.openType === 'edit') {
        // 初始化流程按钮和参数
        this.bpmInstanceObject.bpmEditor.flowEditorInitFunc(this.bpmInstanceObject, {
          entryId: this.urlParams.entryId,
          executionId: this.urlParams.executionId,
          taskId: this.urlParams.taskId,
          formId: this.urlParams.id
        });
      } else {
        this.$message.error('系统错误缺少参数');
      }
    },
    saveAndStartProcess(params) {
      this.$refs.flowDetail[0].saveAndStartProcess(params);
    },
    saveForm(params) {
      this.$refs.flowDetail[0].saveForm(params);
    },
    beforeBpmButtons(params) {
      // 向低版本保持兼容
      if (this.$refs.flowDetail[0].beforeBpmButtons && typeof this.$refs.flowDetail[0].beforeBpmButtons == 'function') {
        return this.$refs.flowDetail[0].beforeBpmButtons(params);
      }

      if (this.$refs.flowDetail[0].beforeClickBpmButtons && typeof this.$refs.flowDetail[0].beforeClickBpmButtons == 'function') {
        return this.$refs.flowDetail[0].beforeClickBpmButtons(params);
      }

      return new Promise((resolve) => {
        resolve(true);
      });
    },
    afterBpmButtons(params) {
      if (this.$refs.flowDetail[0].afterBpmButtons && typeof this.$refs.flowDetail[0].afterBpmButtons == 'function') {
        return this.$refs.flowDetail[0].afterBpmButtons(params);
      }

      if (this.$refs.flowDetail[0].afterClickBpmButtons && typeof this.$refs.flowDetail[0].afterClickBpmButtons == 'function') {
        return this.$refs.flowDetail[0].afterClickBpmButtons(params);
      }
      return true;
    },
    flowCustomFunction(params) {
      this.$refs.flowDetail[0].flowCustomFunction(params);
    },
    changeFlowCustomVars(params) {
      this.flowCustomVars = Object.assign({}, this.flowCustomVars, params);
    },
    scrollViewByTab(tab) {
      if (this.flowDetailShowType === 'tab') {
        this.activeKey1 = String(tab.order - 1);
      } else if (this.flowDetailShowType === 'collapse') {
        if (tab.id) {
          this.$refs[tab.id][0].scrollIntoView({ behavior: 'smooth' });
        }
      }
    },
    handleScroll() {
      const { scrollTop } = this.$refs.flowBody;
      if (scrollTop > 0 && scrollTop - this.contentLastScrollTop > 0) {
        this.isScrollDown = true;
      } else {
        this.isScrollDown = false;
      }
      this.contentLastScrollTop = scrollTop;
    },
    refreshWindow() {
      if (!this.params && this.viewMode !== 'detailForm' && !['inTab', 'inModal'].includes(this.eformMode)) {
        if (window.name.indexOf('isReload') !== -1) {
          this.$Modal.warning({
            title: '系统提示',
            content:
              '流程参数错误！无法初始化权限按钮！您可能是通过非法的途径进入了当前页面，例如重复刷新页面，拷贝链接到浏览器地址栏等操作。点击确定关闭表单',
            okText: '确定',
            cancelText: '取消',
            onOk: () => {
              window.close();
            }
          });
        } else {
          window.name = `${window.name}isReload`;
        }
      }
    },

    /* 查看详情 */
    changeTabs() {
      this.isSteps = !this.isSteps;

      if (this.isSteps) {
        this.switchTitle = '查看详情';
      } else {
        this.switchTitle = '查看时间轴';
      }
    },
    BpmButTrack() {
      this.showBpmButTrack = !this.showBpmButTrack;
    },
    // 文字跟踪切换按钮
    changeHeadTag(e) {
      if (settings.flowDetailShowType === 'pushDown') {
        this.currentTab = e;
      } else {
        this.currentTab = e.type;
      }
    },
    // 打开父流程
    unfoldFather() {
      this.fatherVisible = true;
    },
    // 关闭父流程
    closeFather() {
      this.fatherVisible = false;
    },
    // 获取是否有父流程
    getParentprocess() {
      if (this.bpmInstanceObject.bpmModel.entryId) {
        const parameter = {
          entryId: this.bpmInstanceObject.bpmModel.entryId
        };
        httpAction(this.getParentprocessParam.url, parameter, this.getParentprocessParam.method).then((res) => {
          if (res.success) {
            this.fatherEntryId = res.data;
          }
        });
      }
    },
    inModalResize(h) {
      const ch = this.viewMode === 'detailForm' ? 48 : 104;
      this.modeStyle = {
        // 104为modal头高度+流程页头高度
        height: h > ch ? `${h - ch}px` : 0
      };
    },

    selectSubFlow(callback) {
      this.visible = true;
      this.selectSubFlowCallback = callback;
    },

    // 关联父流程后刷新流程图
    selectParentFlow() {
      this.$refs.bpmInstanceChart.refreshFlowChart();
    },
    handleCancel() {
      this.visible = false;
    },
    onChoose(val) {
      this.preConfirmedModel = val;
    },
    handleConfirm() {
      const { title, deploymentId, version } = this.preConfirmedModel;
      if (!deploymentId) {
        this.$message.warning('请先选择一条流程');
        return;
      }
      this.visible = false;
      this.selectSubFlowCallback(deploymentId, title, version);
    }
  }
};
</script>

<style lang="less">
@import '@/views/avic/bpm/flowdetail/assets/styles/flow-detail.less';
.defaut-flow-detail {
  .flow-detail-content-spin {
    & > .ant-spin {
      position: fixed !important;
    }
  }
  .flow-detail .layout .x6-graph-scroller {
    max-height: 320px !important;
  }
}
</style>
